<template>
  <ul class='m-context-menu'>
    <!-- 循环菜单项，事件带参数抛出 -->
    <li
      v-for='item in rightclickInfo.menulists'
      :key='item.btnName'
      class='m-context-menu-item'
      @click.stop='fnHandler(item)'
    >
      <div class='m-context-menu-item-btn'>
        <!-- 图标和按钮名 -->
        <i
          :class='item.icoName'
          class='m-icon'
        />
        <span>{{ item.btnName }}</span>
      </div>
    </li>
  </ul>
</template>
<script>
  export default {
    name: 'ContextMenu',
    props: {
      // 接收右键点击的信息
      rightclickInfo: {
        type: Object,
        default: () => {
          return {
            position: {
              x: null,
              y: null,
            },
            menulists: [
              {
                fnName: '', // 事件名
                params: {}, // 点击的参数
                icoName: '',
                btnName: ''
              },
            ],
          }
        },
      },
      classIndex: {
        type: Number,
        default: 0,
      },
    },
    watch: {
      // 监听右键点击时点击位置的变化弹出右键菜单
      'rightclickInfo.position' (val) {
        let x = val.x
        let y = val.y
        let innerWidth = window.innerWidth
        let innerHeight = window.innerHeight
        /**
         * 注意，这里要使用getElementsByClassName去选中对应dom，因为右键菜单组件可能被多处使用
         * classIndex标识就是去找到对应的那个右键菜单组件的，需要加的
         * */
        let menu =
          document.getElementsByClassName('m-context-menu')[this.classIndex]
        menu.style.display = 'block'
        let menuHeight = this.rightclickInfo.menulists.length * 30 // 菜单容器高
        let menuWidth = 180 // 菜单容器宽
        // 菜单的位置计算
        menu.style.top =
          (y + menuHeight > innerHeight ? innerHeight - menuHeight : y) + 'px'
        menu.style.left =
          (x + menuWidth > innerWidth ? innerWidth - menuWidth : x) + 'px'
        // 绑定鼠标点击事件，通过e.button判断点击的是否是左键，左键关闭菜单
        document.addEventListener('mouseup', this.hide, false)
      },
    },
    methods: {
      hide (e) {
        if (e.button === 0) {
          // 0是左键、1是滚轮按钮或中间按钮、2鼠标右键
          let menu = document.getElementsByClassName('m-context-menu')[this.classIndex]
          menu.style.display = 'none' // 菜单关闭
          document.removeEventListener('mouseup', this.hide) // 解绑监听事件
        }
      },
      fnHandler (item) {
        this.$emit(item.fnName, item.params)
        // 传出去为：('事件名',事件参数)
      },
    }
  }
</script>
<style scoped lang='scss'>
.m-context-menu {
  color: #333;
  background: #fff;
  border-radius: 4px;
  list-style-type: none;
  box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, 0.3);
  font-size: 12px;
  font-weight: 500;
  box-sizing: border-box;
  padding: 4px 0;
  // 固定定位，高层级，初始隐藏，右击时显示
  position: fixed;
  z-index: 3000;
  display: none;
  &-item {
    box-sizing: border-box;
    padding: 6px 12px;
    border-radius: 4px;
    transition: all 0.36s;
    cursor: pointer;
    &-item-btn {
      .m-icon {
        margin-right: 4px;
      }
    }
  }
  &-item:hover {
    background-color: #ebf5ff;
    color: #6bacf2;
  }
}
</style>
